// app/service/user.js

const Service = require('egg').Service;


class UserService extends Service {
  async createArticle() {
    const { ctx } = this
    const { article } = ctx.request.body;
    const { title, description, body, tagList } = article
    // 如果认为文章标题是唯一的，可以使用 findOne() 方法查询指定标题的文章信息。
    // 如果认为文章的标题、描述、正文、作者和标签等属性的组合条件是唯一的，可以使用 findOne() 方法根据多个属性的组合条件查询文章信息。
    const queryArticle = await ctx.model.Article.findOne({ title });
    console.log('queryArticle', queryArticle)
    if (queryArticle) {
        ctx.throw(ctx.errorMap.articleExists.code, ctx.errorMap.articleExists.message);
    }
    const username = ctx.state.user.username
    const currentUser = await ctx.model.User.findOne({ username });
    console.log('aaa', currentUser)
    if(currentUser) {
        let _id = currentUser.toObject()._id

        let slug = ctx.handleSlug(title)
        console.log('slug2', slug)
        const articleData = await ctx.model.Article.create({ title, slug, description, body, tagList, author: ctx.app.mongoose.Types.ObjectId(_id) });
        return articleData ? articleData.toObject() : articleData
    } else {
        ctx.throw(ctx.errorMap.notFoundAuthor.code, ctx.errorMap.notFoundAuthor.message);
    }
  }
  async listArticles() {
    const { ctx } = this
    let { tag, author, favorited, limit = 10, offset = 0 } = ctx.query;
    console.log('listArticles111', author, tag)
    // 当有查询条件再去设置，否则会出现报错 $and/$or/$nor must be a nonempty array 
    let queryParams = {
    }
    console.log('222', queryParams['$and'])
    
    if(author) {
      const userArticle  = await ctx.model.User.findOne({ username: author });
      console.log('userArticle', userArticle)
      if(userArticle) {
        let _id = ctx.app.mongoose.Types.ObjectId(userArticle._id)
        if(!queryParams['$and']) queryParams['$and'] = []
        queryParams['$and'].push({ author: _id  })
      } else {
        // console.log('用户文章不存在')
        ctx.throw(ctx.errorMap.notFoundAuthorArticle.code, ctx.errorMap.notFoundAuthorArticle.message);
      }
    }
    console.log('listArticle1')
    // favorited 这个后面来看下
    try {
      // && Array.isArray(tag)
      if(tag && typeof tag === 'string') {
        // 如果要匹配数组多个成员，需要在 $elemMatch 操作符中使用多个查询条件，以逗号分隔。
        if(!queryParams['$and']) queryParams['$and'] = []
        queryParams['$and'].push({
          tagList: { $elemMatch: { $in: tag } }
        })
      }
    } catch (error) {
      console.log('error type --> tag', error)
    }
    console.log(queryParams, offset, limit, tag)
    try {
      limit = Number(limit)
      offset = Number(offset)
    } catch (error) {
      console.log('error type --> offset/limit', error)
    }
    // 在 Mongoose 中，可以使用 skip() 和 limit() 方法来进行分页查询。
    const queryArticle = await ctx.model.Article.find(queryParams).skip(offset).limit(limit);;
    // console.log('listArticlesaa', queryArticle)
    // console.log('listArticlesbb', queryArticle.toObject())
    return queryArticle
  }
  async getArticle() {
    const { ctx } = this
    const { slug } = ctx.params
    const article  = await ctx.model.Article.findOne({ slug });
    return article
  }
  async updateArticle() {
    const { ctx } = this
    const { article } = ctx.request.body;
    const { title, description, body } = article
    let params = {}
    if(title) params.title = title
    if(description) params.description = description
    if(body) params.body = body
    const result = await ctx.model.Article.updateOne(params);
    console.log('updateArticle', result)
    return result
  }
  async deleteArticle() {
    const { ctx } = this
    const { slug } = ctx.params
    const result = await ctx.model.Article.deleteOne({ slug });
    console.log('deleteArticle', result)
    return result
  }
  async feedArticles() {
    const { ctx } = this
    let { limit = 10, offset = 0 } = ctx.params
    try {
      limit = Number(limit)
      offset = Number(offset)
    } catch (error) {
      console.log('error type --> offset/limit', error)
    }
    let queryParams = {}
    
    console.log(limit, offset)
    const username = ctx.state.user.username
    const currentUser = await ctx.model.User.findOne({ username });
    console.log(currentUser, currentUser.following, currentUser.following.length)
    if(currentUser && currentUser.following && currentUser.following.length > 0) {
      queryParams['author'] = { $in: currentUser.following }
    }
    console.log( queryParams)
    const queryArticle = await ctx.model.Article.find(queryParams).skip(offset).limit(limit);
    return queryArticle
  }
  async favoriteArticle() {
    const { ctx } = this
    console.log('favoriteArticle00', ctx.state.user)
    let { username } = ctx.state.user
    const { slug } = ctx.params
    console.log('favoriteArticle0', username)
    const currentUser = await ctx.model.User.findOne({ username })
    console.log('favoriteArticle1')
    if(currentUser) {
      const currentArticle = await ctx.model.Article.findOne({ slug });
      console.log('favoriteArticle2')
      if (!currentArticle) {
        ctx.throw(ctx.errorMap.articleNotFound.code, ctx.errorMap.articleNotFound.message);
      }
      const currentUserId = ctx.app.mongoose.Types.ObjectId(currentUser._id)
      const currentArticleId = ctx.app.mongoose.Types.ObjectId(currentArticle._id)
      const favorite = await ctx.model.Favorite.findOne({ user: currentUserId, article: currentArticleId });
      console.log('favoriteArticle3')
      if (favorite) {
        ctx.throw(ctx.errorMap.articleAleadyFavorited.code, ctx.errorMap.articleAleadyFavorited.message);
      }
      const newFavorite = await ctx.model.Favorite.create({ user: currentUserId, article: currentArticleId });
      console.log('favoriteArticle4')
      await currentArticle.update({ $inc: { favoritesCount: 1 } });
      console.log('newFavorite', newFavorite)
      return newFavorite
    } else {
        ctx.throw(ctx.errorMap.notFoundAuthor.code, ctx.errorMap.notFoundAuthor.message);
    }
  }
  async unfavoriteArticle() {
    const { ctx } = this
    console.log('unfavoriteArticle00', ctx.state.user)
    let { username } = ctx.state.user
    const { slug } = ctx.params
    console.log('unfavoriteArticle0', username)
    const currentUser = await ctx.model.User.findOne({ username })
    console.log('unfavoriteArticle1')
    if(currentUser) {
      const currentArticle = await ctx.model.Article.findOne({ slug });
      console.log('unfavoriteArticle2')
      if (!currentArticle) {
        ctx.throw(ctx.errorMap.articleNotFound.code, ctx.errorMap.articleNotFound.message);
      }
      const currentUserId = ctx.app.mongoose.Types.ObjectId(currentUser._id)
      const currentArticleId = ctx.app.mongoose.Types.ObjectId(currentArticle._id)
      const favorite = await ctx.model.Favorite.findOne({ user: currentUserId, article: currentArticleId });
      console.log('unfavoriteArticle3', favorite)
      if (!favorite) {
        ctx.throw(ctx.errorMap.articleNotFavorited.code, ctx.errorMap.articleNotFavorited.message);
      }
      let result = await ctx.model.Favorite.deleteOne({ user: currentUserId, article: currentArticleId })
      console.log('unfavoriteArticle4', result)
      await currentArticle.update({ $inc: { favoritesCount: -1 } });
      // console.log('newFavorite', newFavorite)
      return result
    } else {
        ctx.throw(ctx.errorMap.notFoundAuthor.code, ctx.errorMap.notFoundAuthor.message);
    }
  }
}

module.exports = UserService;